package com.snow.java.base.junit;

import com.snow.java.base.entity.Student;

import java.util.Optional;

/**
 * @类名称：
 * @类描述：
 * @author: bingHeng
 * @Date 2019.04.07
 * @Version: 1.0
*/
public class MyOptional {
    /**
     *  Optional<T>类（java.util.Optional）是一个容器类，代表一个值存在或者不存在，原来null表示一个值不存在，现在Optional可以更好的表示这个概念，并且可以避免空指针异常。
     *
     *  常用方法：
     *      Optional.of(T t): 创建一个Optional实例
     *      Optional.empty(): 创建一个空的Optional实例
     *      Optional.ofNullable(T t): 若 t不为nul，创建Option实例，否则创建空实例
     *      isPresent():判断是否包含值
     *      orElse(T t): 如果调用对象包含值，则返回值，否则返回t
     *      orElseGet(Supplier s): 如果调用对象包含值，则返回值，否则返回s获取到的值
     *      map(Function f): 如果有值对其处理，并返回处理后的Optional，否则返回Optional.empty()
     *      flatMap(Function mapper): 与map类似，要求返回值必须是Optional
     *
     */

    public static void main(String[] args) {

        // of  参数不能为null，否则会报错 空指针异常
        Optional<Student> student = Optional.of(new Student());
        System.out.println(student.get());

        // empty 允许构建一个空的Optional 对象，但是空对象的时候没有值，此时会报出java.util.NoSuchElementException: No value present的异常
        Optional<Student> empty = Optional.empty();
//        System.out.println(empty.get());

        // ofNullable, 是以上两个的结合体
        Optional<Student> o = Optional.ofNullable(null);
//        System.out.println(o.get());

        // isPresent
        if(o.isPresent()) {
            System.out.println(o.get());
        } else {
            System.out.println("如果对象有值，那么我就打印if中的值，否则我就else输出这句话，证明了该对象中没有值");
        }

        // orElse // 如果o对象中有值，那么就输出o对象，否则我就新new一个
        Student student1 = o.orElse(new Student(1, "张三丰", 2, 3, 4, Student.Status.BUSY));
        System.out.println(student1);

        //orElseGet 参数为一个供给型接口，生成对象常用到此接口，同时此处传递的为函数性接口，那么意味着可以写自己想要的功能
        Student student2 = o.orElseGet(Student::new);
        System.out.println(student2);

        // map
        Optional<Student> s = Optional.of(new Student(2, "三丰", 2, 3, 4, Student.Status.BUSY));
        String s1 = s.map(Student::getName).get();
        System.out.println(s1);

        // flatMap  返回的必须是一个Optional对象，进一步避免了空指针异常
        String s2 = s.flatMap((e) -> Optional.ofNullable(e.getName())).get();
        System.out.println(s2);

    }
}
